<template>
    <el-cascader :options="treeData" :props="cascaderProps" class="g-width100"
                 ref="cascader"
                 clearable
                 :size="size"
                 :placeholder="placeholder"
                 :disabled="disabled"
                 :show-all-levels="showAllLevels"
                 :collapse-tags="true"
                 :filterable="filterable"
                 :filter-method="filterMethod"
                 :debounce="500"
                 v-model="localValue"
                 v-on:focus="handleFocus($event)"
                 v-on:blur="handleBlur($event)"
                 v-on:change="emitChange"
                 v-on:input="emitInput"
    ></el-cascader>
</template>

<script>
    export default {
        name: 'SelectCascader',
        props: {
            value: {
                required: true
            },
            // 显示的名称，目前仅用于回显
            labelText: {
                type: String
            },
            dataUrl: {
                type: String,
                required: true
            },
            // 初始加载时添加请求参数
            initDataParamFormat: {
                type: Function
            },
            // 懒加载子节点添加请求参数
            loadChildrenDataParamFormat: {
                type: Function
            },
            // medium / small / mini
            size: {
                type: String,
                default: 'mini'
            },
            placeholder:{
                type: String,
                default: '请选择'
            },
            disabled:{
                type: Boolean,
                default: false
            },
            // 输入框中是否显示选中值的完整路径
            showAllLevels:{
                type: Boolean,
                default: false
            },
            filterable:{
                type: Boolean,
                default: false
            },
            filterMethod:{
                type: Function,
                default:function (node, keyword) {

                    console.log(node,keyword)
                    return true
                }
            },
            // 次级菜单的展开方式
            // click / hover
            propExpandTrigger:{
                type: String,
                default: 'click'
            },
            // 是否多选
            propMultiple:{
                type: Boolean,
                default: false
            },
            // 在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false
            propCheckStrictly: {
                type: Boolean,
                default: false
            },
            // 在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
            propEmitPath:{
                type: Boolean,
                default: false
            },
            // 是否动态加载子节点，需与 lazyLoad 方法结合使用
            propLazy: {
                type: Boolean,
                default: true
            },
            propValue:{
                type: String,
                default: 'id'
            },
            propLabel: {
                type: String,
                default: 'name'
            },
            propChildren: {
                type: String,
                default: 'children'
            },
            propDisabled:{
                type: String,
                default: 'disabled'
            },
            propLeaf:{
                type: String,
                default: 'hasChildren'
            },
        },
        computed:{
            cascaderProps(){
                return {
                    expandTrigger:this.propExpandTrigger,
                    // 是否多选
                    multiple:this.propMultiple,
                    // 在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false
                    checkStrictly: this.propCheckStrictly,
                    // 在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
                    emitPath: this.propEmitPath,
                    // 是否动态加载子节点，需与 lazyLoad 方法结合使用
                    lazy: this.propLazy,
                    value: this.propValue,
                    label: this.propLabel,
                    children: this.propChildren,
                    disabled: this.propDisabled,
                    leaf: this.propLeaf,
                    lazyLoad: this.loadChildren
                }
            }
        },
        data() {
            return {
                localValue: this.value,
                treeData: null,
                treeLoading: false,
            }
        },
        mounted() {
            this.initLabelText(this.labelText)
            this.loadTreeData()
        },
        methods: {
            // 树过滤匹配
            treeFilterNode(value, data) {
                if (!value) return true
                return data.node[this.label].indexOf(value) !== -1
            },
            // 刷新按钮，重新加载树数据
            treeRefreshBtnClick() {
                this.loadTreeData()
            },
            // 初始化回显
            initLabelText(labelText) {
                if(labelText){
                    if(!this.propMultiple){
                        // 斩不支持多选回显
                        let cascader = this.$refs.cascader
                        console.log(cascader)
                        if(cascader){
                            let input = cascader.$el.getElementsByTagName("input")[0]
                            input.value = labelText
                        }
                    }
                }
            },
            loadChildren(node, resolve) {
                if (!node.data) {
                    return
                }
                this.$emit('lazyLoadingBegin', node.data)
                let params = {parentId: node.data.id}
                if (this.loadChildrenDataParamFormat) {
                    let p = this.loadChildrenDataParamFormat(this.relationFilterModal)
                    if (p) {
                        for (let key in p) {
                            params[key] = p[key]
                        }
                    }
                }
                this.axios.get(this.dataUrl, {params: params})
                    .then((response) => {
                        let content = response.data
                        this.handleDataForAttr (content)
                        resolve(content)
                        this.$emit('lazyLoadingEnd', node.data, content)
                    })
                    .catch((error) => {
                        resolve([])
                        this.$emit('lazyLoadingEnd', node.data, [])
                        if (error.response) {
                            if (error.response.status == 401) {
                                return
                            }
                            if (error.response.status != 404) {
                                this.$message.error(error.response.data.msg)
                            }
                        } else {

                            this.$message.error('网络错误或服务不可用')
                        }
                    }).finally(() => {

                })
            },
            // 如果返回的数据有node属性这里合理化一下
            handleDataForAttr(content){

                content.forEach(item=>{
                    if(item.node){
                        if(item[this.propLabel] == undefined && item.node[this.propLabel]){
                            item[this.propLabel] = item.node[this.propLabel]
                        }
                        if(item[this.propChildren] == undefined && item.node[this.propChildren]){
                            item[this.propChildren] = item.node[this.propChildren]
                        }
                        if(item[this.propDisabled] == undefined && item.node[this.propDisabled]){
                            item[this.propDisabled] = item.node[this.propDisabled]
                        }
                        if(item[this.propLeaf] == undefined && item.node[this.propLeaf]){
                            item[this.propLeaf] = item.node[this.propLeaf]

                        }
                        // 兼容取反
                        if(this.propLeaf == 'hasChildren'){
                            item[this.propLeaf] = !item[this.propLeaf]
                        }
                    }
                })
            },
            // 加载树数据
            loadTreeData() {
                let self = this
                self.treeLoading = true
                let params = {}
                if (this.initDataParamFormat) {
                    let p = this.initDataParamFormat(this.relationFilterModal)
                    if (p) {
                        for (let key in p) {
                            params[key] = p[key]
                        }
                    }
                }
                this.axios.get(this.dataUrl, {params: params})
                    .then((response) => {
                        let content = response.data
                        this.handleDataForAttr (content)
                        self.treeData = content

                    })
                    .catch((error) => {
                        self.treeData = []
                        if (error.response) {
                            if (error.response.status == 401) {
                                return
                            }
                            if (error.response.status != 404) {
                                this.$message.error(error.response.data.msg)
                            }
                        } else {
                            self.$message.error('网络错误或服务不可用')
                        }
                    }).finally(() => {
                    self.treeLoading = false
                })
            },
            getCheckedNodes(leafOnly) {
                return this.$refs.cascader.getCheckedNodes(leafOnly)
            },
            getSelectData(val){
                let checkedNodes = this.$refs.cascader.getCheckedNodes()
                if(checkedNodes && checkedNodes.length > 0){
                    let r = []
                    checkedNodes.forEach((item)=>{
                        r.push(item)
                    })
                    if(r.length == 1 && !this.propMultiple){
                        return r[0]
                    }
                    return r
                }
                return null
            },
            handleFocus (event) {
                this.$emit('focus', event)
            },
            handleBlur (event) {
                this.$emit('blur', event)
            },
            emitChange (val) {
                this.$emit('change', val)
                console.log(this.getCheckedNodes())
                this.$emit('selectData', this.getSelectData(val))
            },
            emitInput (val) {
                this.$emit('input', val)
                this.$emit('selectData', this.getSelectData(val))
            },
        },
        watch: {
            value(val){
                this.localValue = val
            },
            dataUrl(val) {
                this.loadTreeData()
            },
            labelText(val){
                this.initLabelText(val)
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
